package com.tpsix.util;

import com.tpsix.domain.SysDept;
import com.tpsix.domain.SysMenu;
import com.tpsix.dto.Tree;
import lombok.experimental.UtilityClass;

import java.util.*;

@UtilityClass
public class TreeBuilder {

    public <T> Tree<T> build(List<Tree<T>> nodes) {

        if (nodes == null) {
            return null;
        }
        List<Tree<T>> topNodes = new ArrayList<Tree<T>>();

        for (Tree<T> children : nodes) {

            int pid = children.getParentId();
            if (pid == 0) {
                topNodes.add(children);

                continue;
            }

            for (Tree<T> parent : nodes) {
                int id = parent.getId();
                if (id == pid) {
                    parent.getChildren().add(children);
                    children.setHasParent(true);
                    parent.setHasChildren(true);
                }
            }

        }

        Tree<T> root = new Tree<T>();
        if (topNodes.size() == 1) {
            root = topNodes.get(0);
        } else {
            root.setId(-1);
            root.setParentId(0);
            root.setHasParent(false);
            root.setHasChildren(true);
            root.setChecked(true);
            root.setChildren(topNodes);
            root.setText("顶级节点");
            Map<String, Object> state = new HashMap<>(16);
            state.put("opened", true);
            root.setState(state);
        }

        return root;
    }

    public <T> List<Tree<T>> buildList(List<Tree<T>> nodes, int idParam) {
        if (nodes == null) {
            return null;
        }
        List<Tree<T>> topNodes = new ArrayList<Tree<T>>();

        for (Tree<T> children : nodes) {

            int pid = children.getParentId();
            if (idParam == pid) {
                topNodes.add(children);
                continue;
            }

            for (Tree<T> parent : nodes) {
                int id = parent.getId();
                if (id == pid) {
                    parent.getChildren().add(children);
                    children.setHasParent(true);
                    parent.setHasChildren(true);
                }
            }

        }
        return topNodes;
    }

    public void menuTreeBuild(List<SysMenu> menuList, List<SysMenu> menus, int menuType) {
        for (SysMenu sysMenu : menuList) {
            List<SysMenu> children = new ArrayList<>();
            for (SysMenu menu : menus) {
                if (menuType == 1 && menu.getType() == 2) {
                    // 如果是获取类型不需要按钮，且菜单类型是按钮的，直接过滤掉
                    continue;
                }
                if (sysMenu.getId() != null && sysMenu.getId().equals(menu.getParentId())) {
                    menu.setParentName(sysMenu.getTitle());
                    menu.setLevel(sysMenu.getLevel() + 1);
                    if (exists(children, menu)) {
                        children.add(menu);
                    }
                }
            }
            sysMenu.setChildren(children);
            children.sort(Comparator.comparing(SysMenu::getSort));
            menuTreeBuild(children, menus, menuType);
        }
    }

    /**
     * 构建部门tree
     *
     * @param sysDepts
     * @param depts
     */
    public void deptTreeBuild(List<SysDept> sysDepts, List<SysDept> depts) {

        for (SysDept sysDept : sysDepts) {
            List<SysDept> children = new ArrayList<>();
            for (SysDept dept : depts) {
                if (sysDept.getId() != null && sysDept.getId().equals(dept.getParentId())) {
                    dept.setParentName(sysDept.getName());
                    dept.setLevel(sysDept.getLevel() + 1);
                    children.add(dept);
                }
            }
            sysDept.setChildren(children);
            deptTreeBuild(children, depts);
        }
    }

    /**
     * 判断菜单是否存在
     *
     * @param sysMenus
     * @param sysMenu
     * @return
     */
    public boolean exists(List<SysMenu> sysMenus, SysMenu sysMenu) {
        boolean exist = false;
        for (SysMenu menu : sysMenus) {
            if (menu.getId().equals(sysMenu.getId())) {
                exist = true;
            }
        }
        return !exist;
    }


}
